#include <string.h>
#include <type.h>

int strlen(char* str) {
    int len = 0;
    while (str[len++] != '\0')
        ;
    return len - 1;
}

// a is equal to b?
int strcmp(char* s1, char* s2) {
    int len = strlen(s1);
    if (len != strlen(s2))
        return 0;
    for (int i = 0; i < len; i++) {
        if (s1[i] != s2[i]) {
            return 0;
        }
    }
    return 1;
}

char* itoa(long xx, char* str, int base, int sign) {
    static char digits[] = "0123456789ABCDEF";
    char buf[16];
    int i;
    unsigned long x;

    if (sign && (sign = xx < 0)) {
        x = -xx;
    } else {
        x = xx;
    }

    i = 0;
    do {
        buf[i++] = digits[x % base];
    } while ((x /= base) != 0);

    if (sign)
        buf[i++] = '-';

    if (base == 16) {
        buf[i++] = 'x';
        buf[i++] = '0';
    }
    int len = i;
    str[len--] = '\0';
    while (--i >= 0)
        str[len - i] = buf[i];
    return str;
}

void* memset(void* ptr, char v, int n) {
    asm volatile("movl %1, %%edi\n"
        "rep stosb\n" ::"c"(n),
        "r"(ptr),
        "a"(v)
        : "edi", "memory");
    return ptr;
}

void* memcpy(void* dst, const void* src, int n) {
    asm volatile("movl %1, %%edi\n"
        "rep movsb\n" ::"S"(src),
        "r"(dst),
        "c"(n)
        : "edi", "memory");
    return dst;
}

char* strcpy(char* dst, const char* src) {
    char c;
    unsigned int i = 0;
    while ((c = src[i])) {
        dst[i] = c;
        i++;
    }
    dst[i] = '\0';
    return dst;
}

char* strncpy(char* dst, const char* src, int len) {
    char c;
    int i = 0;
    while ((c = src[i]) && i <= len) {
        dst[i++] = c;
    }
    while (i <= len) {
        dst[i++] = '\0';
    }
    return dst;
}

#define WS_CHAR(c)                                                             \
    (c == ' ' || c == '\t' || c == '\n' || c == '\f' || c == '\v' || c == '\r')

void strrtrim(char* str) {
    size_t l = strlen(str);
    while (l < (size_t)-1) {
        char c = str[l];
        if (!c || WS_CHAR(c)) {
            l--;
            continue;
        }
        break;
    }
    str[l + 1] = '\0';
}